﻿using SharpSoft.WPF; 
using SharpSoft.WPF.Controls;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;

namespace System
{
    /// <summary>
    /// UI相关的扩展
    /// </summary>
    public static class UIExtension
    {
        /// <summary>
        /// 获取控件的UI内容为图片
        /// </summary>
        /// <param name="visual"></param>
        /// <param name="pixelFormat"></param>
        /// <param name="dpi"></param>
        /// <returns></returns>
        public static RenderTargetBitmap GetBitmap(this FrameworkElement visual, PixelFormat pixelFormat, double dpi = 96)
        {
            RenderTargetBitmap bitmap = new RenderTargetBitmap((int)visual.ActualWidth, (int)visual.ActualHeight, dpi, dpi, pixelFormat);
            DrawingVisual dv = new DrawingVisual();
            using (DrawingContext ctx = dv.RenderOpen())
            {//先渲染到DrawingVisual，避免出现图片位置有偏移的情况
                VisualBrush vb = new VisualBrush(visual) { AutoLayoutContent = true };
                ctx.DrawRectangle(vb, null,
                    new Rect(new Point(0, 0), new Size((int)visual.ActualWidth, (int)visual.ActualHeight)));
            }

            bitmap.Render(visual);
            return bitmap;
        }


        #region DrawingContext
        /// <summary>
        /// 绘制多边形
        /// </summary>
        /// <param name="drawingContext"></param>
        /// <param name="brush"></param>
        /// <param name="pen"></param>
        /// <param name="points"></param>
        /// <param name="fill_rule"></param>
        /// <param name="draw_polygon">是否闭合多边形</param>
        public static void DrawPolygonOrPolyline(
                        this DrawingContext drawingContext,
                        Brush brush, Pen pen,
                        Point[] points, FillRule fill_rule,
                        bool draw_polygon)
        {
            if (points == null || points.Length == 0)
            {
                return;
            }
            StreamGeometry geo = new StreamGeometry();
            geo.FillRule = fill_rule;

            using (StreamGeometryContext context = geo.Open())
            {
                context.BeginFigure(points[0], true, draw_polygon);
                context.PolyLineTo(points.Skip(1).ToArray(), true, false);
            }

            drawingContext.DrawGeometry(brush, pen, geo);
        }

        /// <summary>
        /// 绘制文本
        /// </summary>
        /// <param name="dc"></param>
        /// <param name="center"></param>
        /// <param name="text"></param>
        /// <param name="emSize"></param>
        /// <param name="brush"></param>
        /// <param name="typeface"></param>
        /// <param name="flowDirection"></param>
        public static void DrawText(this DrawingContext dc, Point center, string text, double emSize, Brush brush, Typeface typeface, FlowDirection flowDirection = FlowDirection.LeftToRight)
        {
            if (string.IsNullOrEmpty(text))
            {
                return;
            }
            FormattedText ft = new FormattedText(text, Globalization.CultureInfo.CurrentCulture, flowDirection, typeface, emSize, brush);
            var p = new Point(center.X - ft.Width / 2, center.Y - ft.Height / 2);
            dc.DrawText(ft, p);
        }

        /// <summary>
        /// 测算渲染文字的尺寸
        /// </summary>
        /// <param name="dc"></param>
        /// <param name="text"></param>
        /// <param name="emSize"></param>
        /// <param name="typeface"></param>
        /// <param name="flowDirection"></param>
        /// <returns></returns>
        public static Size MeasureText(this DrawingContext dc, string text, double emSize, Typeface typeface, FlowDirection flowDirection = FlowDirection.LeftToRight)
        {
            FormattedText ft = new FormattedText(text, Globalization.CultureInfo.CurrentCulture, flowDirection, typeface, emSize, Brushes.Black);
            return new Size(ft.MinWidth, ft.Height);
        }
        #endregion

        public static void dlgSuccess(this DispatcherObject fe, string msg)
        {
            MessageBox.Show(msg, "完成", MessageBoxButton.OK, MessageBoxImage.Information);
        }
        public static void dlgError(this DispatcherObject fe, string msg, Exception ex = null)
        {
            SharpSoft.WPF.App.ErrorDialog dlg = new SharpSoft.WPF.App.ErrorDialog();
            dlg.Title = "异常";
            dlg.Message = msg;
            dlg.ShowDialogForMain();
            // MessageBox.Show(msg, "异常", MessageBoxButton.OK, MessageBoxImage.Error);
        }
        /// <summary>
        /// 显示等待遮罩层
        /// </summary>
        /// <param name="fe"></param>
        /// <param name="isbusy"></param>
        public static void busy(this FrameworkElement fe, bool isbusy, object content = null)
        {
            var busy = (BusyIndicator)fe.FindName("busy");
            if (busy != null)
            {
                busy.BusyContent = content;
                busy.IsBusy = isbusy;
            }
        }
     

        public static bool? DialogChildren(this Window parent, Window child)
        {
            child.Owner = parent;
            return child.ShowDialog();
        }
        //从Handle中获取Window对象
        static Window GetWindowFromHwnd(IntPtr hwnd)
        {
            return (Window)HwndSource.FromHwnd(hwnd).RootVisual;
        }

        //GetForegroundWindow API
        [DllImport("user32.dll")]
        static extern IntPtr GetForegroundWindow();

        //调用GetForegroundWindow然后调用GetWindowFromHwnd
        static Window GetTopWindow()
        {
            var hwnd = GetForegroundWindow();
            if (hwnd == null)
                return null;

            return GetWindowFromHwnd(hwnd);
        }

        //显示对话框并自动设置Owner
        public static void ShowDialogForMain(this Window win)
        {
            win.Owner = GetTopWindow();
            win.ShowInTaskbar = false;
            win.ShowDialog();
        }

        /// <summary>
        /// 获取DataGrid的所有行是否存在验证错误。
        /// </summary>
        /// <param name="dg">要检查的DataGrid实例</param>
        /// <returns>true 有错，false 无错</returns>
        public static bool GetDataGridRowsHasError(this DataGrid dg)
        {
            bool hasError = false;
            for (int i = 0; i < dg.Items.Count; i++)
            {
                DependencyObject o = dg.ItemContainerGenerator.ContainerFromIndex(i);
                hasError = Validation.GetHasError(o);
                if (hasError)
                {
                    break;
                }
            }
            return hasError;
        }
    }
}
